package com.piece.core.db.util;

import com.piece.core.framework.enums.sql.SqlOperator;
import com.piece.core.framework.enums.sql.SqlRelation;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.string.StringUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
import java.util.Map.Entry;

public class SearchFilter {

    public String key;
    public String fieldName;
    public Object value;
    public SqlOperator operator;
    public SqlRelation relation;

    public SearchFilter(String key, String fieldName, SqlOperator operator, SqlRelation relation, Object value) {
        this.key = key;
        this.fieldName = fieldName;
        this.value = value;
        this.operator = operator;
        this.relation = relation;
    }

    /**
     * 查询条件转换
     *
     * @param searchParams 参数名称
     *                     Q_字段名称_类别_条件_关联关系<br>
     *                     Q: 固定查询标识<br>
     *                     字段名称:  属性名称<br>
     *                     类别:  S:string、 L:long、 DOU:double、 INT:int、 BD:BigDecimal、 FL:float、 SH:short、 D:date<br>
     *                     条件:  LT:<、 GT:>、 EQ:=、 LE:<=、 GE:>=、 LK:like、 NLK:not like、 EMP:empty、 NEMP:not empty、
     *                     NULL:null、 NNULL:not null、IN:in、 NIN:not in、 NEQ:!=<br>
     *                     关联关系: AND、OR，默认为AND
     */
    public static Collection<SearchFilter> parse(Map<String, Object> searchParams) {
        Collection<SearchFilter> filters = new ArrayList<>();

        for (Entry<String, Object> entry : searchParams.entrySet()) {
            // 过滤掉空值
            String name = entry.getKey();
            Object value = entry.getValue();
            String key = "default";

            if (!name.startsWith("Q_")) {
                SearchFilter filter = null;
                if (((value instanceof Object[]))
                        || ((value instanceof Collection))) {
                    filter = new SearchFilter(key, name, SqlOperator.IN, SqlRelation.AND, value);
                } else {
                    filter = new SearchFilter(key, name, SqlOperator.EQ, SqlRelation.AND, Convert.toStr(value));
                }
                filters.add(filter);
                continue;
            }

            String[] names = StringUtils.split(name, "_");
            String filedName = names[1];
            SqlOperator operator = SqlOperator.valueOf(names[3]);
            if (operator != SqlOperator.NULL && operator != SqlOperator.NNULL
                    && operator != SqlOperator.EMP && operator != SqlOperator.NEMP
                    && value == null) {
                continue;
            }

            // 拆分operator、relation、filedAttribute
            boolean hasRelation = (name.split("_").length == 5);
            SqlRelation relation = SqlRelation.AND;
            String symbol;
            if (hasRelation) {
                symbol = names[4];
                key = StringUtil.extractMessage(symbol, '(', ')');
                symbol = symbol.replace("(" + key + ")", "");
                if (StringUtils.isEmpty(key)) {
                    key = "default";
                }
                relation = SqlRelation.valueOf(symbol.toUpperCase());
            }

            // 重新赋值value
            symbol = names[2];
            switch (operator) {
                case IN:
                case NIN:
                case BTW:
                    value = generateListValue(symbol, value);
                    break;
                default:
                    value = Convert.invert(symbol, value);
            }

            // 创建searchFilter
            SearchFilter filter = new SearchFilter(key, filedName, operator, relation, value);
            filters.add(filter);
        }

        return filters;
    }

    private static List generateListValue(String symbol, Object value) {
        if (value instanceof Collection) {
            return (List) value;
        } else {
            if ("INT".equals(symbol)) {
                return Arrays.asList(Convert.toIntArray(Convert.toStr(value)));
            } else if ("L".equals(symbol)) {
                return Arrays.asList(Convert.toLongArray(Convert.toStr(value)));
            } else if ("D".equals(symbol)) {
                return Arrays.asList(Convert.toDateArr(Convert.toStr(value)));
            } else {
                return Arrays.asList(Convert.toStrArray(Convert.toStr(value)));
            }
        }
    }
}
